﻿using ASmile.Com;
using ASmile.Com.Menu;
using ASmile.DBModel;
using ASmile.Win.Controls;
using ASmile.Win.Extend;
using System;
using System.Windows.Forms;

namespace ASmile.Win.Forms
{
    public partial class FrmMenu : FrmBase
    {
        public FrmMenu()
        {
            InitializeComponent();
        }

        IMenuBLL BLLObj { get; } = ObjectFactory.GetObject<IMenuBLL>("MenuBLL");

        /// <summary>
        /// 当前选中的菜单分类对象
        /// </summary>
        Sys_Menu CurrMenuTree { get; set; }

        private void FrmMenu_Load(object sender, EventArgs e)
        {
            RefreshTreeData();
            tvMenu.AllowDropNode = true;
            tvMenu.DropNodeBefore += TvMenu_DropNodeBefore;
            tvMenu.AfterSelect += TvMenu_AfterSelect;

            if (IsManager)
            {
                toolStripTop1.LoopItem(SetRights);

                void SetRights(ToolStripItem item)
                {
                    if (!item.Enabled) item.Enabled = item.Visible = true;
                }
            }
            dgvMenu.SetDropMove<Sys_Menu>(SwapOrderNo);
            dgvMenu.SetInputEdit<Sys_Menu>(Sys_Menu.CNOrderNo, txtMenuOrderNo, SetMenuOrderNo);
            SetCopyInsertSql<Sys_Menu>(dgvMenu);
        }

        bool SetMenuOrderNo(Sys_Menu model, EditText txt)
        {
            var ret = BLLObj.SetOrderNo(new ArgSetSortNo 
            {
                Id = model.Id,
                SortNo = (int)txtMenuOrderNo.Value
            });
            ShowMessage(ret.msg);
            return ret.success;
        }

        void SwapOrderNo(Sys_Menu src, Sys_Menu tar)
        {
            var ret =
            BLLObj.SwapOrderNo(new ArgSwapOrderNo
            {
                SrcId = src.Id,
                TarId = tar.Id,
                SrcOrderNo = src.OrderNo,
                TarOrderNo = tar.OrderNo
            });
            ShowMessage(ret.msg);
            if (ret)
            {
                tar.OrderNo += src.OrderNo;
                src.OrderNo = tar.OrderNo - src.OrderNo;
                tar.OrderNo = tar.OrderNo - src.OrderNo;
                dgvMenu.Refresh();
            }

        }

        #region 菜单树操作

        /// <summary>
        /// 初始化指定控件的tree数据
        /// </summary>
        void InitTreeData(TreeViewEx tv, ContextMenuStrip cmNodeOperate)
        {
            var treeData = BLLObj.GetTreeData().data;
            tv.InitTreeViewData(treeData, SetTreeNode);
        }

        void SetTreeNode(TreeNode node, Sys_Menu m)
        {
            node.Name = m.Id;
            node.Tag = m;
            node.Text = $"{m.OrderNo:D2}.{m.MenuCaption}";
            if (!m.IsMenu)
            {
                node.ImageIndex = 0;
                node.SelectedImageIndex = 0;
                node.ContextMenuStrip = cmNodeOperate;
            }
            else
            {
                node.ImageIndex = 1;
                node.SelectedImageIndex = 1;
            }
        }

        void RefreshTreeData()
        {
            InitTreeData(tvMenu, cmNodeOperate);
            CurrMenuTree = null;
            dgvMenu.DataSource = null;
        }

        private void TvMenu_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var selMenu = e.Node.Tag as Sys_Menu;
            if (selMenu.IsMenu) return;
            CurrMenuTree = selMenu;
            RefreshMenuData();
        }

        private bool TvMenu_DropNodeBefore(TreeNode moveNode, TreeNode targetNode)
        {
            var selMenu = targetNode.Tag as Sys_Menu;
            if (selMenu.IsMenu)
            {
                ShowMessage("不能拖动到菜单项");
                return false;
            }

            var m = moveNode.Tag as Sys_Menu;
            m.OrderNo = targetNode.Nodes.Count;
            m.PId = targetNode.Name;
            var r = BLLObj.SetParent(
                new ArgSetParent
                {
                    SrcId = m.Id,
                    TarPId = targetNode.Name,
                    OrderNo = targetNode.Nodes.Count + 1
                });
            //m.Id, targetNode.Name, targetNode.Nodes.Count + 1);
            ShowMessage(r.msg);
            return r.success;
        }

        private void tsBtnAddTree_Click(object sender, EventArgs e)
        {
            var model = new Sys_Menu
            {
                OrderNo = tvMenu.Nodes.Count + 1
            };
            FrmMenuTreeEdit frm = new FrmMenuTreeEdit();
            frm.Text += " - 新增";
            var ret = frm.ShowDialog(new EditFormArgs
            {
                SetModel = model,
                SaveHandle = (m) => BLLObj.AddTree(m as Sys_Menu)
            });

            if (ret)
            {
                model.Id = ret.data;
                TreeNode node = new TreeNode();
                SetTreeNode(node, model);
                tvMenu.Nodes.Add(node);
                tvMenu.SelectedNode = node;
                ShowMessage(ret.msg);
            }
        }

        private void tsBtnTreeRefresh_Click(object sender, EventArgs e)
        {
            RefreshTreeData();
        }

        private void tsMenuTreeAddSub_Click(object sender, EventArgs e)
        {
            TreeNode selNode = tvMenu.SelectedNode;
            var model = new Sys_Menu
            {
                PId = selNode.Name,
                PCaption = selNode.FullPath,
                OrderNo = selNode.Nodes.Count + 1
            };
            FrmMenuTreeEdit frm = new FrmMenuTreeEdit();
            frm.Text += " - 新增";
            var ret = frm.ShowDialog(new EditFormArgs
            {
                SetModel = model,
                SaveHandle = (m) => BLLObj.AddTree(m as Sys_Menu)
            });

            if (ret)
            {
                model.Id = ret.data;
                TreeNode node = new TreeNode();
                node.Name = model.Id;
                node.Text = model.MenuCaption;
                SetTreeNode(node, model);
                node.Tag = model;
                selNode.Nodes.Add(node);
                tvMenu.SelectedNode = node;
                ShowMessage(ret.msg);
            }
        }

        private void tsMenuTreeEdit_Click(object sender, EventArgs e)
        {
            TreeNode selNode = tvMenu.SelectedNode;
            if (selNode == null) return;
            Sys_Menu model = selNode.Tag as Sys_Menu;
            if (model == null)
            {
                ShowMessage("错误的节点");
                return;
            }
            model.PCaption = selNode.Parent?.FullPath;
            FrmMenuTreeEdit frm = new FrmMenuTreeEdit();
            frm.Text += " - 修改";
            var ret = frm.ShowDialog(new EditFormArgs
            {
                SetModel = model,
                SaveHandle = (m) => BLLObj.EditTree(m as Sys_Menu)
            });
            if (ret)
            {
                SetTreeNode(selNode, model);
                tvMenu.SelectedNode = selNode;
                ShowMessage(ret.msg);
            }
        }

        private void tsMenuTreeDel_Click(object sender, EventArgs e)
        {
            if (ShowQuestion("确实要移除当前节点吗?", "移除确认"))
            {
                TreeNode selNode = tvMenu.SelectedNode;
                var ret = BLLObj.DelTree(selNode.Tag as Sys_Menu);
                if (ret)
                {
                    //RefreshTreeData();
                    selNode.Remove();
                }
                ShowMessage(ret.msg);
            }
        }

        private void tsMenuTreeSetTop_Click(object sender, EventArgs e)
        {
            if (!ShowQuestion("确实要设置为顶级节点吗?", "设置确认"))
            {
                return;
            }
            var selNode = tvMenu.SelectedNode;
            var ret = BLLObj.SetParent(new ArgSetParent
            {
                SrcId = selNode.Name,
                TarPId = "",
                OrderNo = tvMenu.Nodes.Count + 1
            });

            //selNode.Name, string.Empty, tvMenu.Nodes.Count + 1);
            if (ret)
            {
                var selModel = selNode.Tag as Sys_Menu;
                selModel.PId = string.Empty;
                selModel.OrderNo = tvMenu.Nodes.Count + 1;

                //var newNode = selNode.Clone() as TreeNode;
                //tvMenu.Nodes.Add(newNode);
                TreeNode newNode = new TreeNode();
                SetTreeNode(newNode, selModel);
                tvMenu.Nodes.Add(newNode);
                selNode.Remove();
                tvMenu.SelectedNode = newNode;
            }
            ShowMessage(ret.msg);
        }

        void SwapOrderNo(TreeNode srcNode, TreeNode tarNode)
        {
            var tarModel = tarNode.Tag as Sys_Menu;
            var srcModel = srcNode.Tag as Sys_Menu;
            var ret =
            BLLObj.SwapOrderNo(new ArgSwapOrderNo
            {
                SrcId = srcModel.Id,
                TarId = tarModel.Id,
                SrcOrderNo = srcModel.OrderNo,
                TarOrderNo = tarModel.OrderNo
            });
            if (ret)
            {
                var newSrcNode = srcNode.Clone() as TreeNode;
                var newTarNode = tarNode.Clone() as TreeNode;
                if (tarNode.Level == 0)
                {
                    tvMenu.Nodes.Insert(tarNode.Index, newSrcNode);
                    tvMenu.Nodes.Insert(srcNode.Index, newTarNode);
                }
                else
                {
                    tarNode.Parent.Nodes.Insert(tarNode.Index, newSrcNode);
                    tarNode.Parent.Nodes.Insert(srcNode.Index, newTarNode);
                }
                srcNode.Remove();
                tarNode.Remove();
                tvMenu.SelectedNode = newSrcNode;
            }
            ShowMessage(ret.msg);
        }

        private void tsMenuSetUp_Click(object sender, EventArgs e)
        {
            TreeNode srcNode = tvMenu.SelectedNode;
            TreeNode tarNode = srcNode.PrevNode;
            if (tarNode == null)
            {
                ShowMessage("已经是最上了");
                return;
            }
            SwapOrderNo(srcNode, tarNode);
        }

        private void tsMenuSetDown_Click(object sender, EventArgs e)
        {
            TreeNode srcNode = tvMenu.SelectedNode;
            TreeNode tarNode = srcNode.NextNode;
            if (tarNode == null)
            {
                ShowMessage("已经是最下了");
                return;
            }
            SwapOrderNo(srcNode, tarNode);
        }

        #endregion

        #region 菜单操作

        void RefreshMenuData()
        {
            var ret = BLLObj.GetMenus(
                new ArgSearchMenu
                {
                    PId = CurrMenuTree.Id,
                    SearchVal = tsTxtSearch.Text
                });
            //CurrMenuTree.Id, tsTxtSearch.Text);
            dgvMenu.DataSource = ret.data;
        }

        void AddShow(bool isCopyAdd)
        {
            if (CurrMenuTree == null)
            {
                ShowMessage("请选择一个菜单分类");
                return;
            }

            var selNode = tvMenu.SelectedNode;
            if (selNode == null)
            {
                ShowMessage("请选择菜单分类");
                return;
            }
            Sys_Menu saveModel;
            if (isCopyAdd)
            {
                saveModel = dgvMenu.GetSelectedClassData<Sys_Menu>();
                if (saveModel == null)
                {
                    ShowMessage("没有选中记录");
                    return;
                }
            }
            else
            {
                saveModel = new Sys_Menu();
                saveModel.PId = CurrMenuTree.Id;
            }
            saveModel.OrderNo = dgvMenu.RowCount + 1;
            saveModel.PCaption = selNode.FullPath; //CurrMenuTree.MenuCaption;
            FrmMenuEdit frm = new FrmMenuEdit(dgvMenu.RowCount + 1);
            var arg = new EditFormArgs
            {
                ClearId = true,
                SaveHandle = (menu) => BLLObj.AddMenu(menu as Sys_Menu),
                SaveModel = saveModel,
                SetModel = saveModel
            };
            var ret = frm.ShowDialog(arg);
            if (ret)
            {
                ShowMessage(ret.msg);
                saveModel.Id = ret.data;
                dgvMenu.AddDataSource(saveModel);
            }
        }

        private void tsBtnSearch_Click(object sender, EventArgs e)
        {
            RefreshMenuData();
        }

        private void tsTxtSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                RefreshMenuData();
            }
        }

        private void tsBtnAdd_Click(object sender, EventArgs e)
        {
            AddShow(false);
        }

        private void tsBtnCopyAdd_Click(object sender, EventArgs e)
        {
            AddShow(true);
        }

        private void tsBtnEdit_Click(object sender, EventArgs e)
        {
            var selMenu = dgvMenu.GetSelectedClassData<Sys_Menu>();
            if (selMenu == null)
            {
                ShowMessage("没有选中记录");
                return;
            }
            var selNode = tvMenu.SelectedNode;
            selMenu.PCaption = selNode.FullPath;
            var frm = new FrmMenuEdit();
            frm.Text += " 修改";
            var arg = new EditFormArgs
            {
                SaveHandle = (menu) => BLLObj.EditMenu(menu as Sys_Menu),
                SaveModel = selMenu,
                SetModel = selMenu
            };
            var ret = frm.ShowDialog(arg);
            if (ret)
            {
                ShowMessage(ret.msg);
                dgvMenu.Refresh();
                //RefreshMenuData();
                //RefreshTreeData();
                //tvMenu.SetSelectedNode(selMenu.PId);
            }
        }

        private void tsBtnDelete_Click(object sender, EventArgs e)
        {
            var selModel = dgvMenu.GetSelectedClassData<Sys_Menu>();
            if (selModel == null)
            {
                ShowMessage("没有选中记录");
                return;
            }
            if (!ShowQuestion("确实要删除当前选中记录吗？", "删除确认"))
            {
                return;
            }
            var ret = BLLObj.DelMenu(selModel);
            if (ret)
            {
                //RefreshMenuData();
                //RefreshTreeData();
                //tvMenu.SetSelectedNode(selMenu.PId);
                dgvMenu.DelDataSource(selModel);
            }
            ShowMessage(ret.msg);
        }

        private void tsBtnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        #endregion
    }
}